package com.spider.admin.utils;


import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.spider.admin.conf.ENVConf;
import com.spider.admin.store.primary.model.ClientTenantInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Administrator
 */
@Slf4j
@Component
public class JwtUtil {

    @Autowired
    ENVConf conf;

    /**
     * @param clientTenantInfo
     * @return
     */
    public Map<String, String> createToken(ClientTenantInfo clientTenantInfo) {
        Map<String, String> tokenResult = new HashMap<>();
        //过期时间
        Date expireDate = new Date(System.currentTimeMillis() + conf.getExpiration() * 1000);
        if (clientTenantInfo.getClientId().equals(conf.getClientId())) {
            clientTenantInfo.setManagerClient(true);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        String token = JWT.create()
                // 添加头部
                .withHeader(map)
                //可以将基本信息放到claims中
                //clientKey
                .withClaim("clientId", clientTenantInfo.getClientId())
                .withClaim("clientKey", clientTenantInfo.getClientKey())
                //appKey
                .withClaim("tenantKey", clientTenantInfo.getTenantKey())
                .withClaim("clientName", clientTenantInfo.getClientName())
                .withClaim("tenantName", clientTenantInfo.getTenantName())
                .withClaim("managerClient", clientTenantInfo.isManagerClient())
                //超时设置,设置过期的日期
                .withExpiresAt(expireDate)
                //签发时间
                .withIssuedAt(new Date())
                //SECRET加密
                .sign(Algorithm.HMAC256(DigestUtils.md5DigestAsHex(conf.getSecret().getBytes(StandardCharsets.UTF_8))));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String date = sdf.format(expireDate.getTime());
        tokenResult.put("accessToken", token);
        tokenResult.put("expires", date);
        return tokenResult;
    }

    /**
     * 校验token并解析token
     */
    public Map<String, Object> verifyToken(String token) {
        DecodedJWT jwt;
        Map<String, Object> rv = new HashMap<>();
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(DigestUtils.md5DigestAsHex(conf.getSecret().getBytes(StandardCharsets.UTF_8)))).build();
            jwt = verifier.verify(token.replace("Bearer ", ""));
            rv.put("clientId", jwt.getClaims().get("clientId").asString());
            rv.put("clientKey", jwt.getClaims().get("clientKey").asString());
            rv.put("tenantKey", jwt.getClaims().get("tenantKey").asString());
            rv.put("clientName", jwt.getClaims().get("clientName").asString());
            rv.put("tenantName", jwt.getClaims().get("tenantName").asString());
            rv.put("managerClient", jwt.getClaims().get("managerClient").asBoolean());
            rv.put("verify", true);
        } catch (Exception e) {
            rv.put("verify", false);
        }

        return rv;
    }


}
